Skip to content

Clojure client #467

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
jwr opened this issue May 23, 2025 · 11 comments
Open

Clojure client #467

jwr opened this issue May 23, 2025 · 11 comments

Comments

@jwr
Copy link
Contributor

jwr commented May 23, 2025

I am in a situation where a Clojure sente client would be a very good fit. I took a quick look at Sente code and (unless I'm misunderstanding things) it seems this doesn't currently exist: there is an assumption that the client will be in ClojureScript.

Is this assumption deeply baked in?

This is not a "feature request" yet: I am trying to compare various approaches and learn what is feasible.

@ptaoussanis
Copy link
Member

@jwr Hi Jan!

There is support for a Java WebSocket client - does that maybe help in your case?

If not, could you please explain in a little more detail what you're trying to do and what you might need from Sente?

@jwr
Copy link
Contributor Author

jwr commented May 25, 2025

It seems this is exactly what I was looking for. I took another look at the source code to check why I didn't realize that a Clojure client is there. There were two reasons for this:

  1. I first looked at make-channel-socket! and start-chsk-router!, both of which are conditionalized to start the server in Clojure and client in ClojureScript.
  2. The way make-channel-socket-client! is indented made it seem like it is part of the CLJS conditional starting on line 1873. But it isn't! The conditional actually encloses only new-ChAutoSocket.

In other words, I should have looked closer!

@ptaoussanis
Copy link
Member

No worries, it's easy to miss and not explicitly documented anywhere IIRC. Happy to hear that this addresses your case!

Feel free to ping if you run into any issues.

@jwr
Copy link
Contributor Author

jwr commented May 26, 2025

So far I noticed that cb-success? and cb-error? are conditionalized and ClojureScript-only, not sure why. I don't think they need to be?

#?(:cljs (defn cb-error?   [cb-reply-clj] (#{:chsk/closed :chsk/timeout :chsk/error} cb-reply-clj)))
#?(:cljs (defn cb-success? [cb-reply-clj] (not (cb-error? cb-reply-clj))))

@ptaoussanis
Copy link
Member

So far I noticed that cb-success? and cb-error? are conditionalized and ClojureScript-only, not sure why. I don't think they need to be?

Good catch, these should be available to Clojure too. Have just pushed https://clojars.org/com.taoensso/sente/versions/1.21.0-alpha3 with the change 👍

@jwr
Copy link
Contributor Author

jwr commented May 27, 2025

Here are some more little things that threw me off:

The event-msg alias isn't actually used anywhere, I just spent some time chasing it while trying to find other errors. The assumption in that conditional isn't correct anymore:

(def event-msg? #?(:clj server-event-msg? :cljs client-event-msg?))

Similarly, this alias assumes that ClojureScript is always a client:

(def start-chsk-router!
  "Platform-specific alias for `start-server-chsk-router!` or
  `start-client-chsk-router!`. Please see the appropriate aliased fn
  docstring for details."
  #?(:clj  start-server-chsk-router!
     :cljs start-client-chsk-router!))

And finally, a bigger issue: I couldn't find a good way to conditionally disable CSRF protection. To provide some context, I have a server that handles requests from both ClojureScript clients, which do need CSRF protection, and from Clojure clients that use a different authentication method, where CSRF is not required. The current approach with csrf-token-fn lets me disable CSRF protection altogether when starting the server, but that's not what I need: I need to disable it only for requests that have been authenticated with an API key.

I am not sure what the right solution here is. I think I would like to provide a :check_csrf? function taking a request that would determine whether CSRF should be checked for that particular request or not.

I worked around this with a kludge by copying the automatically generated CSRF token from the request into params, where Sente normally expects it.

@ptaoussanis
Copy link
Member

ptaoussanis commented May 27, 2025

Hi Jan!

Here are some more little things that threw me off

Thanks! I've never tried Sente with a Clojure client myself, and I'm not sure if anyone's actively using it that way - so it's definitely possible you'll run into some small issues.

The event-msg alias isn't actually used anywhere [...] Similarly, this alias assumes that ClojureScript is always a client:

These are examples of aliases for backwards compatibility. Sente did originally assume that client <=> Cljs. Once that assumption was loosened, more specific names functions were added (like server-event-msg?, start-server-chsk-router!, etc.) for folks wanting to be specific.

But the old behaviour was retained under these aliases to support pre-existing users.

And finally, a bigger issue: I couldn't find a good way to conditionally disable CSRF protection.

Would it help if the csrf-token-fn could return something like :sente/skip-CSRF-check? That way your (csrf-token-fn [ring-req] ...) could choose to either return a reference token, or the special keyword. Here is the relevant code.

@jwr
Copy link
Contributor Author

jwr commented May 27, 2025

These are examples of aliases for backwards compatibility

I only reported those because they are confusing (and arguably incorrect) if Sente is used in client-mode from Clojure, in case you wanted to officially support this kind of usage.

Would it help if the csrf-token-fn could return something like :sente/skip-CSRF-check? That way your (csrf-token-fn [ring-req] ...) could choose to either return a reference token, or the special keyword.

Yes, I think this would solve the problem in an elegant way!

@ptaoussanis
Copy link
Member

I only reported those because they are confusing (and arguably incorrect)

Have just expanded the docstrings to hopefully make these less confusing.

Yes, I think this would solve the problem in an elegant way!>

Done 👍 Pushed to https://clojars.org/com.taoensso/sente/versions/1.21.0-alpha4.

@jwr
Copy link
Contributor Author

jwr commented May 27, 2025

I can confirm that this works very well and lets me skip the CSRF check when needed. Thank you! 🙏

@ptaoussanis
Copy link
Member

Great, thanks for the quick confirmation 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants